package cn.yz.service.impl;

import cn.yz.dto.RoleDto;
import cn.yz.dto.RolePageDto;
import cn.yz.entity.Role;
import cn.yz.entity.RoleMenu;
import cn.yz.entity.UserRole;
import cn.yz.exception.BusinessException;
import cn.yz.mapper.RoleMapper;
import cn.yz.mapper.RoleMenuMapper;
import cn.yz.mapper.UserRoleMapper;
import cn.yz.service.RoleService;
import cn.yz.vo.PageVo;
import cn.yz.vo.RoleVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;
import cn.yz.util.SecurityUserUtil;

/**
 * 角色服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    private final RoleMapper roleMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMenuMapper roleMenuMapper;

    @Override
    public PageVo<RoleVo> getRolePage(RolePageDto rolePageDto) {
        // 构建查询条件
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(rolePageDto.getName())) {
            queryWrapper.like(Role::getName, rolePageDto.getName());
        }
        if (StringUtils.hasText(rolePageDto.getCode())) {
            queryWrapper.like(Role::getCode, rolePageDto.getCode());
        }
        if (rolePageDto.getStatus() != null) {
            queryWrapper.eq(Role::getStatus, rolePageDto.getStatus());
        }
        if (StringUtils.hasText(rolePageDto.getRemark())) {
            queryWrapper.like(Role::getRemark, rolePageDto.getRemark());
        }
        
        // 排序
        if (StringUtils.hasText(rolePageDto.getSortField())) {
            if ("asc".equalsIgnoreCase(rolePageDto.getSortOrder())) {
                queryWrapper.orderByAsc(Role::getCreateTime);
            } else {
                queryWrapper.orderByDesc(Role::getCreateTime);
            }
        } else {
            queryWrapper.orderByDesc(Role::getCreateTime);
        }

        // 分页查询
        Page<Role> pageParam = new Page<>(rolePageDto.getPage(), rolePageDto.getSize());
        IPage<Role> pageResult = this.page(pageParam, queryWrapper);

        // 转换为VO
        List<RoleVo> roleVos = pageResult.getRecords().stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());

        return new PageVo<>(
                roleVos,
                pageResult.getTotal(),
                pageResult.getCurrent(),
                pageResult.getSize()
        );
    }

    @Override
    public List<RoleVo> getUserRoles(String userId) {
        return roleMapper.selectUserRoles(userId);
    }

    @Override
    public List<RoleVo> getRoleList(String name, String code, Integer status) {
        return roleMapper.selectRoleList(name, code, status);
    }

    @Override
    public RoleVo getRoleById(String id) {
        RoleVo role = roleMapper.selectRoleById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        
        // 获取角色的菜单ID列表
        List<String> menuIds = roleMenuMapper.selectRoleMenuIds(id);
        role.setMenuIds(menuIds);
        
        return role;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(RoleDto roleDto) {
        // 创建角色
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        roleMapper.insert(role);
        
        // 分配菜单权限
        if (CollectionUtils.isNotEmpty(roleDto.getMenuIds())) {
            assignRoleMenus(role.getId(), roleDto.getMenuIds());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(String id, RoleDto roleDto) {
        Role existingRole = roleMapper.selectById(id);
        if (existingRole == null) {
            throw new BusinessException("角色不存在");
        }

        // 更新角色信息
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        role.setId(id);
        roleMapper.updateById(role);
        
        // 更新菜单权限
        updateRoleMenus(id, roleDto.getMenuIds());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(String id) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 检查是否有用户使用该角色
        List<UserRole> userRoles = userRoleMapper.selectByRoleId(id);
        if (CollectionUtils.isNotEmpty(userRoles)) {
            throw new BusinessException("该角色已被用户使用，无法删除");
        }

        // 删除角色菜单关联
        roleMenuMapper.deleteByRoleId(id);
        
        // 删除角色
        roleMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignUserRoles(String userId, List<String> roleIds) {
        // 删除原有用户角色关联
        userRoleMapper.deleteByUserId(userId, SecurityUserUtil.getCurrentUsername());

        // 添加新的用户角色关联
        if (CollectionUtils.isNotEmpty(roleIds)) {
            List<UserRole> userRoles = roleIds.stream().map(roleId -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                return userRole;
            }).collect(Collectors.toList());
            userRoleMapper.insertBatch(userRoles);
        }
    }
    
    /**
     * 分配角色菜单权限
     */
    private void assignRoleMenus(String roleId, List<String> menuIds) {
        if (CollectionUtils.isNotEmpty(menuIds)) {
            List<RoleMenu> roleMenus = menuIds.stream().map(menuId -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                return roleMenu;
            }).collect(Collectors.toList());
            roleMenuMapper.insertBatch(roleMenus);
        }
    }
    
    /**
     * 更新角色菜单权限
     */
    private void updateRoleMenus(String roleId, List<String> menuIds) {
        // 删除原有菜单权限
        roleMenuMapper.deleteByRoleId(roleId);
        
        // 分配新的菜单权限
        if (CollectionUtils.isNotEmpty(menuIds)) {
            assignRoleMenus(roleId, menuIds);
        }
    }

    /**
     * 转换Role实体为RoleVo
     */
    private RoleVo convertToVo(Role role) {
        RoleVo roleVo = new RoleVo();
        BeanUtils.copyProperties(role, roleVo);
        roleVo.setStatusName(getStatusName(role.getStatus()));
        return roleVo;
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 1:
                return "正常";
            case 0:
                return "禁用";
            default:
                return "未知";
        }
    }
} 